<template>
  <div ref="dom" v-click-outside="handleClickOutSide" class="c-dropdown" @click="handleClick">
    <slot />
    <Teleport to="body">
      <div
        v-if="dropdownModel.isOpen"
        ref="dropItemDom"
        class="c-dropdown-menu"
        :style="dropdownModel.menuStyle"
        @mouseup.stop
      >
        <slot name="dropdown" />
      </div>
    </Teleport>
  </div>
</template>
<script lang="ts" setup>
import { ref, computed, watch, watchEffect, reactive, onMounted, onBeforeUnmount, PropType, inject, provide, withDefaults, nextTick, useSlots } from "vue";
import { DropdownModel, DivDom } from './DropdownModel';
import { ClickOutside as vClickOutside } from 'element-plus';
import { Direction } from "@/constants/constants";

const props = withDefaults(
  defineProps<{
    maxHeight?: number,
    maxWidth?: number,
    placement?: Direction,
    trigger?: string,
    disabled?: boolean,
    hideOnScroll?: boolean,
    customEvent?: boolean
  }>(),
  {
    maxHeight: undefined,
    placement: Direction.BOTTOM,
    trigger: 'click',
    hideOnScroll: true,
    customEvent: false
  });

const emit = defineEmits<{
  (event: 'visible-change', visible: boolean): void
}>();
const dom = ref<DivDom>(undefined);
const dropItemDom = ref<DivDom>(undefined);
const dropdownModel = reactive(new DropdownModel()) as DropdownModel;
dropdownModel.hideOnScroll = props.hideOnScroll === undefined ? true : props.hideOnScroll;
dropdownModel.dropItemDom = dropItemDom;
provide('dropdownModel', dropdownModel);

defineExpose({
  dropdownModel,
});

watch(() => dropdownModel.isOpen, (val: boolean) => {
  if (val){
    nextTick(() => {
      dropdownModel.updateMenuStyle(dropItemDom.value, props.maxHeight, props.placement, props.maxWidth);
    });
  }
  emit('visible-change', val);
});

function handleClick() {
  if (props.disabled) return;
  if (props.customEvent) {
    return;
  }
  dropdownModel.toggelOpen();
}

function handleClickOutSide() {
  dropdownModel.close();
}

onMounted(() => {
  setTimeout(() => {
    dropdownModel.dom = dom.value;
  }, 10);

});
onBeforeUnmount(() => {
  dropdownModel.destroy();
});

</script>
<style lang="scss">
.c-dropdown-menu {
  position: absolute;
  overflow: auto;
  border-radius: 2px;
  padding: 4px;
  background-color: white;
  box-shadow: 0px 9px 28px 8px rgba(0, 0, 0, 0.05), 0px 6px 16px 0px rgba(0, 0, 0, 0.08), 0px 3px 6px -4px rgba(0, 0, 0, 0.12);
  border: 1px solid #E0E0E0;
  .el-checkbox{
    height: 100%;
  }
}
</style>

